package io.modifier.basic.ext

import android.content.Context
import android.content.ContextWrapper
import android.content.pm.ActivityInfo
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.core.graphics.toColorInt
import androidx.fragment.app.FragmentActivity
import com.nlf.calendar.Lunar
import com.nlf.calendar.Solar
import com.wquick.base.utils.BitmapUtilW
import com.wquick.base.utils.tools.dayMillis
import com.wquick.base.utils.tools.dayOfMonth
import com.wquick.base.utils.tools.hourOfDay
import com.wquick.base.utils.tools.monthOfYear
import com.wquick.base.utils.tools.second2HourMinuteSecond
import com.wquick.base.utils.tools.years
import io.modifier.basic.core.log.logx.LogX
import io.modifier.basic.ext.findActivity
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.lang.IllegalArgumentException
import java.util.*

//<editor-fold desc="Color">

fun String.toViewColorInt(): Int {
    var ori = this
    if (ori.contains("#").not()) ori = "#$ori"
    if (ori.length !in arrayOf(7, 9)) throw IllegalArgumentException("颜色不正确")
    return ori.toColorInt()
}

fun String.toColor(): Color = Color(this.toViewColorInt())

fun Context.res2ComposeColor(id: Int): Color {
    return Color(this.resources.getColor(id, this.theme))
}


//</editor-fold>


//<editor-fold desc="ms">

typealias Ms = Long

fun Ms.toCalendar(): Calendar = Calendar.getInstance().apply { time = Date(this@toCalendar) }

fun Ms.getChineseWeekChar(): String {
    val calendar = toCalendar()
    val dayOfWeek: Int = calendar.get(Calendar.DAY_OF_WEEK)
    val daysOfWeek = arrayOf("日", "一", "二", "三", "四", "五", "六")
    return daysOfWeek[dayOfWeek - 1]
}

fun Ms.getNongLi(): String {
    val dateMs = this
    val lunar = Lunar(Solar.fromDate(Date().apply { time = dateMs }))
    return "${lunar.monthInChinese}月${lunar.dayInChinese}"
}

fun Ms.getHourMinSec(): List<String> {
    return getTimeByStamp(this).reversed().take(3).map { it.toString() }.reversed()
}

fun getTimeByStamp(timestamp: Long): List<Int> {
    val calendar: Calendar = Calendar.getInstance()
    calendar.time = Date(timestamp)

    val year: Int = calendar.get(Calendar.YEAR)
    val month: Int = calendar.get(Calendar.MONTH) + 1 // Calendar.MONTH 从0开始
    val day: Int = calendar.get(Calendar.DAY_OF_MONTH)

    val hour: Int = calendar.get(Calendar.HOUR_OF_DAY)
    val minute: Int = calendar.get(Calendar.MINUTE)
    val second: Int = calendar.get(Calendar.SECOND)

    return listOf(year, month, day, hour, minute, second)
}

fun getDifferSecToNextDay(): Int {
    val nowMill = System.currentTimeMillis()
    val nextDayMill = System.currentTimeMillis() + dayMillis - 120 * 1000
    val calendar = Calendar.getInstance().apply {
        set(nextDayMill.years, nextDayMill.monthOfYear - 1, nextDayMill.dayOfMonth, 0, 0)
    }
    val delta = calendar.timeInMillis - nowMill
    LogX.d("到明天还有秒:${delta.second2HourMinuteSecond()}")
    val sec = (delta / 1000).toInt()
    return sec
}

fun isNight(): Boolean = run {
    val timeMillis = System.currentTimeMillis()
    val hourOfDay = timeMillis.hourOfDay
    return@run (hourOfDay > 17 || hourOfDay < 6)
}

//</editor-fold>

fun Int.numberToUpperCase(): String {
    val units = arrayOf("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖")
    val nums = arrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

    val numberStr = this.toString()
    val sb = StringBuilder()

    for (c in numberStr) {
        val num = c.toString().toInt()
        val index = nums.indexOf(num)
        if (index < 0 || index > 9) continue
        sb.append(units[index])
    }

    return sb.toString()
}

fun Context.copyUriToFileDir(uri: Uri, fileName: String): String {
    val inputStream = this.contentResolver.openInputStream(uri)
    val tempDir = File(this.filesDir, "temp")
    tempDir.mkdir()
    var path = ""
    if (inputStream != null) {
        val file = File("$tempDir/$fileName")
        val fos = FileOutputStream(file)
        val bis = BufferedInputStream(inputStream)
        val bos = BufferedOutputStream(fos)
        val byteArray = ByteArray(1024)
        var bytes = bis.read(byteArray)
        while (bytes > 0) {
            bos.write(byteArray, 0, bytes)
            bos.flush()
            bytes = bis.read(byteArray)
        }
        bos.close()
        fos.close()
        path = file.path
    }
    return path
}

fun String.decodeSampledBitmapFromPath(reqWidth: Int, reqHeight: Int): Bitmap? {
    val filePath = this
    // 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
    val options = BitmapFactory.Options()
    options.inJustDecodeBounds = true
    BitmapFactory.decodeFile(filePath, options)
    // 调用上面定义的方法计算inSampleSize值
    options.inSampleSize = BitmapUtilW.calculateInSampleSize(options, reqWidth, reqHeight)
    // 使用获取到的inSampleSize值再次解析图片
    options.inJustDecodeBounds = false
    return BitmapFactory.decodeFile(filePath, options)
}

@Composable
fun Landscape() {
    val ctx = LocalContext.current
    ctx.landscape()
}

@Composable
fun Portrait() {
    val ctx = LocalContext.current
    ctx.portrait()
}

@Composable
fun ScreenOrientation(): Int {
    val ctx = LocalContext.current
    return ctx.getScreenOrientation()
}

fun Context.landscape() {
    findActivity()?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}

fun Context.portrait() {
    findActivity()?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}

fun Context.getScreenOrientation(): Int {
    return findActivity()?.requestedOrientation ?: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}

fun Context.setScreenOrientation(flag: Int) {
    findActivity()?.requestedOrientation = flag
}

fun Context.findFragmentActivity(): FragmentActivity {
    var context = this
    while (context is ContextWrapper) {
        if (context is FragmentActivity) return context
        context = context.baseContext
    }
    throw IllegalStateException("findFragmentActivity should be called in the context of an FragmentActivity")
}

fun Context.findAppCompatActivity(): AppCompatActivity {
    var context = this
    while (context is ContextWrapper) {
        if (context is AppCompatActivity) return context
        context = context.baseContext
    }
    throw IllegalStateException("findAppCompatActivity should be called in the context of an AppCompatActivity")
}

fun Int.preAddZero(): String = "${if (this < 10) "0" else ""}$this"

fun Modifier.wStatusBarPadding(): Modifier = composed {
    padding(PaddingValues(top = statusBarH()))
}

fun Modifier.wNavBarPadding(): Modifier = composed {
    padding(PaddingValues(bottom = navBarH()))
}

fun Modifier.wBarsPadding(): Modifier = composed {
    padding(PaddingValues(top = statusBarH(), bottom = navBarH()))
}

@Composable
private fun statusBarH(): Dp {
    return with(LocalDensity.current) {
        var toDp = WindowInsets.statusBars.getTop(this).toDp()
        if (toDp == 0.dp) toDp = 35.dp
//        WLogUtil.d("系统bar 状态栏高度 $toDp - ${toDp.toPx()}")
        toDp
    }
}

@Composable
private fun navBarH(): Dp {
    return with(LocalDensity.current) {
        var toDp = WindowInsets.navigationBars.getTop(this).toDp()
        if (toDp == 0.dp) toDp = 48.dp
//        WLogUtil.d("系统bar 导航栏高度 $toDp - ${toDp.toPx()}")
        toDp
    }
}